package com.qianniu.napi.admin.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.qianniu.napi.admin.entity.User;
import com.qianniu.napi.admin.entity.Xnbi;
import com.qianniu.napi.admin.entity.XnbiFlow;
import com.qianniu.napi.admin.entity.penum.FantimeType;
import com.qianniu.napi.admin.entity.penum.IotypeEnum;
import com.qianniu.napi.admin.entity.penum.JftypeEnum;
import com.qianniu.napi.admin.entity.penum.XftypeEnum;
import com.qianniu.napi.admin.mapper.JifenMapper;
import com.qianniu.napi.admin.mapper.XnbiFlowMapper;
import com.qianniu.napi.admin.mapper.XnbiMapper;
import com.qianniu.napi.admin.service.IUserService;
import com.qianniu.napi.admin.service.IXnbiFlowService;
import com.qianniu.napi.admin.service.IXnbiService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 虚拟币表 服务实现类
 * </p>
 *
 * @author chenxuebin
 * @since 2019-02-22
 */
@Service
public class XnbiServiceImpl extends ServiceImpl<XnbiMapper, Xnbi> implements IXnbiService {

    private final static Logger logger = LoggerFactory.getLogger(XnbiServiceImpl.class);

    @Autowired
    XnbiMapper xnbiMapper;
    @Autowired
    XnbiFlowMapper xnbiFlowMapper;
    @Autowired
    IXnbiFlowService xnbiFlowService;
    @Autowired
    IUserService userService;

    public void addXnbiFlow(Long uid, Long mid, Long mpid, BigDecimal num,
                            Boolean isconfirm, Integer fantimeType,
                            String sn, IotypeEnum iotype, JftypeEnum jftype, String remark, Long ywid) {

        XnbiFlow xflow = new XnbiFlow();
        xflow.setCreatetime(new Date());
        xflow.setIotype(iotype.getVal());
        xflow.setIsConfirm(isconfirm?1:-1);
        if(isconfirm) xflow.setConfirmDate(new Date());
        xflow.setJftype(jftype.getVal());
        xflow.setFantimeType(fantimeType);

        xflow.setUid(uid);
        xflow.setMid(mid);
        xflow.setMpid(mpid);
        xflow.setRemark(remark);
        xflow.setNum(num);
        xflow.setSn(sn);
        xflow.setState(1);
        xflow.setYwid(ywid);
        logger.debug("======xflow=" + xflow);
        xflow.insert();

        Xnbi xbi = null;
        int m = 0;
        Boolean flag = false;
        while (!flag) {
            List<Xnbi> xbis = xnbiMapper.selectList(new EntityWrapper<Xnbi>().eq("uid", uid));
            if (xbis == null||xbis.size()==0) xbi = initXnbi(uid, mid, mpid);
            else xbi = xbis.get(0);

            Long version = xbi.getVersion();
            BigDecimal total = xbi.getTotal();
            BigDecimal fanliing = xbi.getFanliing();

            if (FantimeType.now.getVal()==fantimeType) xbi.setTotal(iotype.getVal() == 1 ? total.add(num): total.subtract(num));
            else xbi.setFanliing(iotype.getVal() == 1 ?fanliing.add(num): fanliing.subtract(num));

            xbi.setModifytime(new Date());
            xbi.setModifier(uid);
            xbi.setVersion(version + 1);
            // ******* 更新账户表 ********
            m = xnbiMapper.update(xbi, new EntityWrapper<Xnbi>().eq("uid", uid).eq("version", version));
            logger.debug(">>>xnbiService.update m=" + m);
            flag = m>0;
        }
    }

    public Boolean xnbiFlowConfirm(String sn,Long uid){
        boolean flag = false;
        int upcout = 0;
        XnbiFlow xnbiFlow = xnbiFlowService.selectOne(new EntityWrapper<XnbiFlow>().eq("sn", sn));
        Xnbi xnbi = null;
        while (xnbiFlow != null && !flag) {
            List<Xnbi> xnbis = xnbiMapper.selectList(new EntityWrapper<Xnbi>().eq("uid", uid));
            if (xnbis == null||xnbis.size()==0) {
                logger.debug("------------xnbi account at uid=" + uid + " not exist and sn=" + sn);
                logger.debug("------------start to init xnbi");
                xnbi = initXnbi(uid);
            }
            else{
                xnbi = xnbis.get(0);
            }
            if(xnbi==null){
                break;
            }

            xnbiFlow.setIsConfirm(1);
            xnbiFlow.setConfirmDate(new Date());
            xnbiFlow.setModifytime(new Date());
            xnbiFlow.setModifier(uid);

            long version = xnbi.getVersion();
            BigDecimal total = xnbi.getTotal();

            xnbi.setTotal(xnbiFlow.getIotype() == 1 ? total.add(xnbiFlow.getNum()) : total.subtract(xnbiFlow.getNum()));
            xnbi.setModifytime(new Date());
            xnbi.setModifier(uid);
            xnbi.setVersion(version + 1);

            upcout = xnbiMapper.update(xnbi, new EntityWrapper<Xnbi>()
                    .eq("uid", uid).eq("version", version));
            if (upcout>0){
                xnbiFlow.insertOrUpdate();
                flag = true;
            }
        }
        return flag;
    }

    public Xnbi initXnbi(Long uid) {

        User user = userService.selectById(uid);
        if(user==null) return null;
        return initXnbi(uid,user.getMid(),user.getMpid());
    }

    public Xnbi initXnbi(Long uid, Long mid, Long mpid) {

        BigDecimal zero = new BigDecimal(0);

        Xnbi act = new Xnbi();
        act.setUid(uid);
        act.setMid(mid);
        act.setMpid(mpid);

        act.setCreatetime(new Date());
        act.setVersion(1l);
        act.setTotal(zero);
        act.setFanliing(zero);
        act.setState(1);
        act.insert();
        return act;
    }

}
